home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Misc / Wood.0.72 / Sources / UPath.m < prev    next >
Encoding:
Text File  |  1993-08-20  |  8.5 KB  |  371 lines

  1.  
  2.  
  3. #import "UPath.h"
  4. #import "PSWUPath.h"
  5.  
  6. @interface UPath(PrivateMethods)
  7.  
  8. - growParams;
  9. - growOps;
  10.  
  11. @end
  12.  
  13. @implementation UPath
  14.  
  15. //************************************************************************
  16. // creating and destroying
  17.  
  18. - initCountParams:(int)numParams countOps:(int)numOps
  19. {  
  20.    [super init];
  21.    maxParams = numParams;
  22.    maxOps = numOps;
  23.    bboxParams = (float *)NXZoneMalloc([self zone],sizeof(float) * (maxParams + 4));
  24.    bbox = bboxParams;
  25.    params = &bboxParams[4];
  26.    bboxOps = (char *)NXZoneMalloc([self zone],maxOps + 2);
  27.    ops = &bboxOps[2];
  28.    ping = NO;
  29.    [self resetFill];
  30.    return self;
  31. }
  32.    
  33. - init
  34. {  
  35.    [self initCountParams:32 countOps:16];
  36.    return self;
  37. }
  38.  
  39. - free
  40. {
  41.    NX_FREE(bboxParams);
  42.    NX_FREE(bboxOps);
  43.    return [super free];
  44. }
  45.  
  46. - copyFromZone:(NXZone *)zone
  47. {
  48.    UPath *theCopy;
  49.  
  50.    theCopy = [super copyFromZone:zone];
  51.    theCopy->bboxParams = NXZoneMalloc(zone,sizeof(float) * (maxParams + 4));
  52.    theCopy->bboxOps = NXZoneMalloc(zone,maxOps + 2);
  53.    bcopy(bboxParams,theCopy->bboxParams,(sizeParams + 4) * (sizeof(float)/sizeof(char)));
  54.    bcopy(bboxOps,theCopy->bboxOps,sizeOps + 2);
  55.    theCopy->bbox = theCopy->bboxParams;
  56.    theCopy->params = theCopy->bboxParams + 4 * sizeof(float);
  57.    theCopy->ops = theCopy->bboxOps + 2; 
  58.    return theCopy;
  59. }
  60.  
  61. //************************************************************************
  62. // accessing
  63.  
  64. - getBounds:(NXRect *)aRect
  65. {
  66.    NXSetRect(aRect,bbox[0],bbox[1],bbox[2] - bbox[0],bbox[3] - bbox[1]);
  67.    return self;
  68. }
  69.  
  70. //************************************************************************
  71. // defining user path
  72.  
  73. - resetFill
  74. {
  75.    sizeParams = sizeOps = 0;
  76.    cp.x = cp.y = 0.0;
  77.    bbox[0] = bbox[1] = 1.0e6;
  78.    bbox[2] = bbox[3] = -1.0e6;
  79.    bboxOps[0] = dps_ucache;
  80.    bboxOps[1] = dps_setbbox;
  81.    return self;
  82. }
  83.  
  84. - updateBBoxOnX:(float)x andY:(float)y
  85. {
  86.    if(x < bbox[0])
  87.     bbox[0] = x;
  88.    if(y < bbox[1])
  89.     bbox[1] = y;
  90.    if(x > bbox[2])
  91.     bbox[2] = x;
  92.    if(y > bbox[3])
  93.     bbox[3] = y;
  94.    return self;
  95. }
  96.  
  97. - moveto:(float)x :(float)y
  98. {
  99.     if(sizeParams + 2 > maxParams)
  100.         if(![self growParams])
  101.             return nil;
  102.     if(sizeOps + 1 > maxOps)
  103.         if(![self growOps])
  104.             return nil;
  105.     params[sizeParams++] = x;
  106.     params[sizeParams++] = y;
  107.     ops[sizeOps++] = dps_moveto;
  108.     [self updateBBoxOnX:x andY:y];
  109.     cp.x = x;
  110.     cp.y = y;    
  111.     return self;
  112. }
  113.  
  114. - rmoveto:(float)x :(float)y
  115. {
  116.    if(sizeParams + 2 > maxParams)
  117.         if(![self growParams])
  118.             return nil;
  119.    if(sizeOps + 1 > maxOps)
  120.         if(![self growOps])
  121.             return nil;    
  122.    ops[sizeOps++] = dps_rmoveto;
  123.    params[sizeParams++] = x;
  124.    params[sizeParams++] = y;
  125.    cp.x += x;
  126.    cp.y += y;
  127.    [self updateBBoxOnX:cp.x andY:cp.y]; 
  128.    return self;
  129. }  
  130.  
  131. - lineto:(float)x :(float)y
  132. {
  133.     if(sizeParams + 2 > maxParams)
  134.         if(![self growParams])
  135.             return nil;
  136.     if(sizeOps + 1 > maxOps)
  137.         if(![self growOps])
  138.             return nil;
  139.     ops[sizeOps++] = dps_lineto;
  140.     params[sizeParams++] = x;
  141.     params[sizeParams++] = y;
  142.     [self updateBBoxOnX:x andY:y];
  143.     cp.x = x;
  144.     cp.y = y;    
  145.     return self;
  146. }
  147.  
  148. - rlineto:(float)x :(float)y
  149. {
  150.    if(sizeParams + 2 > maxParams)
  151.         if(![self growParams])
  152.             return nil;
  153.    if(sizeOps + 1 > maxOps)
  154.         if(![self growOps])
  155.             return nil;    
  156.    ops[sizeOps++] = dps_rlineto;
  157.    params[sizeParams++] = x;
  158.    params[sizeParams++] = y;
  159.    cp.x += x;
  160.    cp.y += y;
  161.    [self updateBBoxOnX:cp.x andY:cp.y]; 
  162.    return self;
  163. }  
  164.  
  165. - curveto:(float)x1 :(float)y1 :(float)x2 :(float)y2 :(float)x3 :(float)y3
  166. {
  167.    if(sizeParams + 6 > maxParams)
  168.         if(![self growParams])
  169.             return nil;
  170.    if(sizeOps + 1 > maxOps)
  171.         if(![self growOps])
  172.             return nil;
  173.    ops[sizeOps++] = dps_curveto;
  174.    params[sizeParams++] = x1;
  175.    params[sizeParams++] = y1;
  176.    [self updateBBoxOnX:x1 andY:y1];
  177.    params[sizeParams++] = x2;
  178.    params[sizeParams++] = y2;
  179.    [self updateBBoxOnX:x2 andY:y2];
  180.    params[sizeParams++] = x3;
  181.    params[sizeParams++] = y3;
  182.    [self updateBBoxOnX:x3 andY:y3];
  183.    cp.x = x3;
  184.    cp.y = y3;    
  185.    return self;
  186. }
  187.  
  188. - rcurveto:(float)dx1 :(float)dy1 :(float)dx2 :(float)dy2 :(float)dx3 :(float)dy3
  189. {
  190.    if(sizeParams + 6 > maxParams)
  191.         if(![self growParams])
  192.             return nil;
  193.    if(sizeOps + 1 > maxOps)
  194.         if(![self growOps])
  195.             return nil;    
  196.    ops[sizeOps++] = dps_rcurveto;
  197.    params[sizeParams++] = dx1;
  198.    params[sizeParams++] = dy1;
  199.    params[sizeParams++] = dx2;
  200.    params[sizeParams++] = dy2;
  201.    params[sizeParams++] = dx3;
  202.    params[sizeParams++] = dy3;
  203.    [self updateBBoxOnX:cp.x + dx1 andY:cp.y + dx1];
  204.    [self updateBBoxOnX:cp.x + dx2 andY:cp.y + dx2];
  205.    [self updateBBoxOnX:cp.x + dx3 andY:cp.y + dx3];
  206.    cp.x += dx3;
  207.    cp.y += dy3; 
  208.    return self;
  209. }  
  210.  
  211. - arc:(float)x :(float)y :(float)r :(float)ang1 :(float)ang2
  212. {
  213.    if(sizeParams + 5 > maxParams)
  214.         if(![self growParams])
  215.             return nil;
  216.    if(sizeOps + 1 > maxOps)
  217.         if(![self growOps])
  218.             return nil;
  219.    ops[sizeOps] = dps_arc;
  220.    sizeOps = sizeOps + 1;
  221.    params[sizeParams++] = x;
  222.    params[sizeParams++] = y;
  223.    params[sizeParams++] = r;
  224.    params[sizeParams++] = ang1;
  225.    params[sizeParams++] = ang2;
  226.    [self updateBBoxOnX:x + r andY:y + r];
  227.    [self updateBBoxOnX:x - r andY:y - r];   
  228.    cp.x = x + cos(ang2 / 57.3) * r;
  229.    cp.y = y + sin(ang2 / 57.3) * r;    
  230.    return self;
  231. }
  232.  
  233. - arcn:(float)x :(float)y :(float)r :(float)ang1 :(float)ang2
  234. {
  235.    if(sizeParams + 5 > maxParams)
  236.         if(![self growParams])
  237.             return nil;
  238.    if(sizeOps + 1 > maxOps)
  239.         if(![self growOps])
  240.             return nil;
  241.    ops[sizeOps++] = dps_arcn;
  242.    params[sizeParams++] = x;
  243.    params[sizeParams++] = y;
  244.    params[sizeParams++] = r;
  245.    params[sizeParams++] = ang1;
  246.    params[sizeParams++] = ang2;
  247.    [self updateBBoxOnX:x + r andY:y + r];
  248.    [self updateBBoxOnX:x - r andY:y - r];   
  249.    cp.x = x + cos(ang2 / 57.3) * r;
  250.    cp.y = y + sin(ang2 / 57.3) * r;    
  251.    return self;
  252. }
  253.  
  254. - arct:(float)x1 :(float)y1 :(float)x2 :(float)y2 :(float)r
  255. {
  256.    if(sizeParams + 5 > maxParams)
  257.         if(![self growParams])
  258.             return nil;
  259.    if(sizeOps + 1 > maxOps)
  260.         if(![self growOps])
  261.             return nil;
  262.    ops[sizeOps++] = dps_arct;
  263.    params[sizeParams++] = x1;
  264.    params[sizeParams++] = y1;
  265.    params[sizeParams++] = x2;
  266.    params[sizeParams++] = y2;
  267.    params[sizeParams++] = r;
  268.    [self updateBBoxOnX:x1 andY:y1];
  269.    [self updateBBoxOnX:x2 andY:y2];   
  270.    cp.x = x2;
  271.    cp.y = y2;    
  272.    return self;
  273. }
  274.  
  275. - closepath
  276. {
  277.    ops[sizeOps++] = dps_closepath; 
  278.    return self;
  279. }
  280.  
  281.  
  282. //************************************************************************
  283. // sending 
  284.  
  285. - debugSend:(int)op cached:(BOOL)cache
  286. {
  287.    ping = YES;
  288.    return [self send:op cached:cache];
  289. }
  290.  
  291. - send:(int)op cached:(BOOL)cache
  292. {
  293.    NXHandler exception;
  294.  
  295.    exception.code = 0;
  296.       NX_DURING
  297.         if(cache)
  298.         DPSDoUserPath(params, sizeParams, dps_float, bboxOps,
  299.               sizeOps + 2, bbox, op);
  300.         else
  301.             DPSDoUserPath(params, sizeParams, dps_float, bboxOps + 1,
  302.               sizeOps + 1, bbox, op);
  303.     if(ping)
  304.         NXPing();    
  305.       NX_HANDLER
  306.     exception = NXLocalHandler;
  307.       NX_ENDHANDLER
  308.     if(exception.code){
  309.         NXReportError(&exception);
  310.         return nil;
  311.     } else 
  312.         return self;
  313. }
  314.  
  315. //************************************************************************
  316. // archiving
  317.  
  318. - write:(NXTypedStream *)stream
  319. {
  320.    [super write:stream];
  321.    NXWriteTypes(stream,"iiii",&sizeParams,&sizeOps,&maxParams,&maxOps);
  322.    NXWritePoint(stream,&cp);
  323.    NXWriteArray(stream,"f",sizeParams + 4,bboxParams);
  324.    NXWriteArray(stream,"c",sizeOps + 2,bboxOps);
  325.    return self;
  326. }
  327.  
  328. - read:(NXTypedStream *)stream
  329. {
  330.    [super read:stream];
  331.    NXReadTypes(stream,"iiii",&sizeParams,&sizeOps,&maxParams,&maxOps);
  332.    NXReadPoint(stream,&cp);
  333.    bboxParams = NXZoneMalloc([self zone],sizeof(float) * (maxParams + 4));
  334.    bboxOps = NXZoneMalloc([self zone],maxOps + 2);
  335.    NXReadArray(stream,"f",sizeParams + 4,bboxParams);
  336.    NXReadArray(stream,"c",sizeOps + 2,bboxOps);
  337.    return self;
  338. }
  339.  
  340. - awake
  341. {
  342.    [super awake];
  343.    ping = NO;
  344.    bbox = bboxParams;
  345.    params = &bboxParams[4];
  346.    ops = &bboxOps[2];
  347.    return self;
  348. }
  349.               
  350. @end
  351.  
  352. @implementation UPath(PrivateMethods)
  353.  
  354. - growParams
  355. {
  356.        maxParams *= 2;
  357.     bbox = bboxParams = (float *)NXZoneRealloc([self zone], bboxParams,sizeof(float) * (maxParams + 4));
  358.     params = &bboxParams[4]; 
  359.        return self;
  360. }
  361.  
  362. - growOps
  363. {
  364.        maxOps *= 2;
  365.     bboxOps = (char *)NXZoneRealloc([self zone], bboxOps,maxOps + 2);
  366.     ops = &bboxOps[2];
  367.        return self;
  368. }
  369.  
  370. @end
  371.